const vscode = require('vscode');
const path = require('path');
const fs = require('fs-extra');
const { exec } = require('child_process');

/**
 * 配置管理模块
 * 支持本地文件系统和Git仓库
 */
class ConfigManager {
    /**
     * 获取所有模板源配置
     * @returns {Array} 模板源配置数组
     */
    static getTemplateSourcesConfig() {
        const config = vscode.workspace.getConfiguration();
        return config.get('file-template-utils.repositories') || [];
    }
    
    /**
     * 获取所有模板源配置（别名方法，兼容性支持）
     * @returns {Array} 模板源配置数组
     */
    static getRepositories() {
        return this.getTemplateSourcesConfig();
    }

    /**
     * 获取本地模板源配置
     * @returns {Array} 本地模板源配置数组
     */
    static getLocalTemplateSourcesConfig() {
        const sources = this.getTemplateSourcesConfig();
        return sources.filter(source => source.type === 'local');
    }

    /**
     * 获取Git仓库模板源配置
     * @returns {Array} Git仓库模板源配置数组
     */
    static getGitRepositorySourcesConfig() {
        const sources = this.getTemplateSourcesConfig();
        return sources.filter(source => source.type === 'git');
    }

    /**
     * 添加新的模板源配置
     * @param {Object} newSource 新的模板源配置
     * @returns {Promise<void>}
     */
    static async addTemplateSourceConfig(newSource) {
        try {
            const config = vscode.workspace.getConfiguration();
            const sources = this.getTemplateSourcesConfig();
            
            // 检查是否已存在相同名称的模板源
            const existingIndex = sources.findIndex(source => source.name === newSource.name);
            if (existingIndex >= 0) {
                throw new Error(`已存在名为 "${newSource.name}" 的模板源`);
            }
            
            // 添加新的模板源
            sources.push(newSource);
            
            // 更新配置
            await config.update('file-template-utils.repositories', sources, vscode.ConfigurationTarget.Global);
            
            return true;
        } catch (error) {
            console.error('添加模板源配置失败:', error);
            throw error;
        }
    }

    /**
     * 验证本地路径是否有效
     * @param {string} localPath 本地路径
     * @returns {boolean} 路径是否有效
     */
    static validateLocalPath(localPath) {
        try {
            // 检查路径是否存在
            if (fs.existsSync(localPath)) {
                return fs.statSync(localPath).isDirectory();
            }
            
            // 如果路径不存在，尝试创建目录
            fs.mkdirpSync(localPath);
            return true;
        } catch (error) {
            console.error('验证本地路径失败:', error);
            return false;
        }
    }

    /**
     * 验证Git仓库配置是否有效
     * @param {Object} gitConfig Git仓库配置
     * @returns {Promise<boolean>} 配置是否有效
     */
    static async validateGitConfig(gitConfig) {
        try {
            // 检查本地路径是否存在
            if (!gitConfig.localPath || !fs.existsSync(gitConfig.localPath)) {
                // 如果本地路径不存在，尝试创建
                await fs.mkdirp(gitConfig.localPath);
            }
            
            // 检查URL格式
            if (!gitConfig.url) {
                return false;
            }
            
            return true;
        } catch (error) {
            console.error('验证Git仓库配置失败:', error);
            return false;
        }
    }
    
    /**
     * 确保Git仓库已克隆并更新
     * @param {Object} gitConfig Git仓库配置
     * @returns {Promise<boolean>} 操作是否成功
     */
    static async ensureGitRepository(gitConfig) {
        return new Promise(async (resolve, reject) => {
            try {
                const localPath = gitConfig.localPath;
                const url = gitConfig.url;
                const branch = gitConfig.branch || 'master';
                
                // 从Git URL中提取仓库名称
                const repoName = url.split('/').pop().replace('.git', '');
                
                // 确保基础目录存在
                if (!fs.existsSync(localPath)) {
                    await fs.mkdirp(localPath);
                    console.log(`创建本地路径: ${localPath}`);
                }
                
                // 构建完整的仓库路径（localPath/repoName）
                const fullRepoPath = path.join(localPath, repoName);
                
                // 检查仓库目录是否已存在
                if (fs.existsSync(path.join(fullRepoPath, '.git'))) {
                    // 已存在，执行pull更新
                    console.log(`仓库已存在，执行pull更新: ${fullRepoPath}`);
                    exec(`git -C "${fullRepoPath}" pull origin ${branch}`, (error, stdout, stderr) => {
                        if (error) {
                            console.error(`Git pull 失败: ${error.message}`);
                            reject(new Error(`更新Git仓库失败: ${error.message}`));
                            return;
                        }
                        resolve(true);
                    });
                } else {
                    // 检查目录是否存在但不是Git仓库
                    if (fs.existsSync(fullRepoPath)) {
                        const files = await fs.readdir(fullRepoPath);
                        if (files.length > 0) {
                            // 目录存在且不为空，询问用户是否清空
                            reject(new Error(`目标目录已存在且不为空: ${fullRepoPath}，请先清空目录或选择其他路径`));
                            return;
                        } else {
                            // 目录存在但为空，可以直接克隆
                            console.log(`目录存在但为空，可以克隆: ${fullRepoPath}`);
                        }
                    } else {
                        // 目录不存在，创建它
                        await fs.mkdirp(path.dirname(fullRepoPath));
                        console.log(`创建目录: ${path.dirname(fullRepoPath)}`);
                    }
                    
                    // 执行克隆
                    console.log(`克隆仓库到: ${fullRepoPath}`);
                    exec(`git clone -b ${branch} "${url}" "${fullRepoPath}"`, (error, stdout, stderr) => {
                        if (error) {
                            console.error(`Git clone 失败: ${error.message}`);
                            reject(new Error(`克隆Git仓库失败: ${error.message}`));
                            return;
                        }
                        resolve(true);
                    });
                }
            } catch (error) {
                console.error('确保Git仓库操作失败:', error);
                reject(error);
            }
        });
    }
    
    /**
     * 推送Git仓库更改
     * @param {Object} gitConfig Git仓库配置
     * @param {string} commitMessage 提交信息
     * @returns {Promise<boolean>} 操作是否成功
     */
    static async pushGitRepository(gitConfig, commitMessage) {
        return new Promise((resolve, reject) => {
            const localPath = gitConfig.localPath;
            const branch = gitConfig.branch || 'master';
            
            // 添加所有更改
            exec(`git -C "${localPath}" add .`, (error) => {
                if (error) {
                    console.error(`Git add 失败: ${error.message}`);
                    reject(new Error(`添加文件到Git仓库失败: ${error.message}`));
                    return;
                }
                
                // 提交更改
                exec(`git -C "${localPath}" commit -m "${commitMessage}"`, (error) => {
                    if (error) {
                        console.error(`Git commit 失败: ${error.message}`);
                        reject(new Error(`提交更改到Git仓库失败: ${error.message}`));
                        return;
                    }
                    
                    // 推送更改
                    exec(`git -C "${localPath}" push origin ${branch}`, (error) => {
                        if (error) {
                            console.error(`Git push 失败: ${error.message}`);
                            reject(new Error(`推送更改到远程仓库失败: ${error.message}`));
                            return;
                        }
                        
                        resolve(true);
                    });
                });
            });
        });
    }
}

module.exports = ConfigManager;